package wavenotes.model.presentation;

import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.wave.api.Wavelet;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Presentation {
	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Key key;

	@Persistent
	private String title;
	
	@Persistent
	private String author;

	@Persistent
	private Date date;

	@Persistent
	private int currentSlideIndex = -1;
	
	@Persistent
	private Set<Wave> waves;

	/**
	 * The Slides are dependent on the Presentation (i.e. if the presentation is
	 * deleted the slides are too)
	 * 
	 * Using an field for ordering is more efficient than requiring the
	 * datastore to do it based on the List order. - but we are not currently doing that
	 */
	@Persistent
	// @Element(dependent = "true")
	private List<Slide> slides;

	public Presentation(String title, String author, Date date, List<Slide> slides) {
		this.title = title;
		this.author = author;
		this.date = date;
		this.slides = slides;
	}

	public Presentation(String title, String author, Date date) {
		this(title, author, date, null);
	}

	public Presentation() {
		this(null, null, new Date());
	}

	public JSONObject toJSON() throws JSONException {
		JSONObject json = new JSONObject(this);

		JSONArray jsonSlides = new JSONArray();

		for (Slide slide : getSlides()) {
			jsonSlides.put(slide.toJSON());
		}

		json.put("slides", jsonSlides);

		return json;
	}

	public String getEncodedKey() {
		return KeyFactory.keyToString(getKey());
	}

	public Key getKey() {
		return key;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getAuthor() {
		return author;
	}

	public Date getDate() {
		return date;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public int getCurrentSlideIndex() {
		return currentSlideIndex;
	}

	public void setCurrentSlideIndex(int currentSlideIndex) {
		this.currentSlideIndex = currentSlideIndex;
	}

	public List<Slide> getSlides() {
		return slides;
	}

	public void setSlides(List<Slide> slides) {
		this.slides = slides;
	}
	
	public void addSlide(Slide slide) {
		slides.add(slide);
	}
		
	public Set<Wave> getWaves() {
		return waves;
	}

	public void setWaves(Set<Wave> waves) {
		this.waves = waves;
	}
	
	public void addWave(Wave wave) {
		this.waves.add(wave);
	}

	@SuppressWarnings("unchecked")
	public static String getPresentationList(String creator, PersistenceManager pm)
	{
		Query jdoQuery = pm.newQuery(Presentation.class, "author == '" + creator + "'");
		List<Presentation> presentations = (List<Presentation>) jdoQuery.execute();
		String listOfPresentations = "[";
		for (int i = 0; i < presentations.size(); i++)
		{
			Presentation p = presentations.get(i);
			listOfPresentations += "{\"id\":\"" + p.getEncodedKey() + "\", \"name\":\"" + p.getTitle() + "\"}";
			if (i + 1 < presentations.size())
				listOfPresentations += ",";
		}
		listOfPresentations += "]";
		
		return listOfPresentations;
	}
	
	public static String getPresentationList(Wavelet wavelet, PersistenceManager pm)
	{
		return getPresentationList(wavelet.getCreator(), pm);
	}
	
	public static Presentation getPresentation(String key, PersistenceManager pm)
	{
		return pm.getObjectById(Presentation.class, key);
	}
}
